// eslint-disable-next-line @typescript-eslint/no-explicit-any
type EventFun = (...args: any[]) => void;
type EventMap = { [eventName: string]: EventFun[] };

export class Observable {
  private eventListeners: EventMap = {};

  /**
   * 添加事件监听器
   * @param eventName 事件名称
   * @param callback 回调函数
   */
  on(eventName: string, callback: EventFun): void {
    if (!this.eventListeners[eventName]) {
      this.eventListeners[eventName] = [];
    }
    this.eventListeners[eventName].push(callback);
  }

  /**
   * 触发事件
   * @param eventName 事件名称
   * @param args 传递给回调函数的参数
   */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  emit(eventName: string, ...args: any[]): void {
    const callbacks = this.eventListeners[eventName];
    if (callbacks) {
      callbacks.forEach((callback) => callback(...args));
    }
  }

  off(eventName: string, callback?: EventFun): void {
    if (callback) {
      this.eventListeners[eventName] =
        this.eventListeners[eventName]?.filter((cb) => cb !== callback) || [];
    } else {
      delete this.eventListeners[eventName];
    }
  }

  once(eventName: string, callback: EventFun): void {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const wrappedCallback = (...args: any[]) => {
      callback(...args);
      this.off(eventName, wrappedCallback);
    };
    this.on(eventName, wrappedCallback);
  }
}
